package com.steve.summary.saga.编排式.service;

import com.steve.summary.saga.编排式.domain.OrderCancelledEvent;
import com.steve.summary.saga.编排式.domain.OrderCreatedEvent;
import com.steve.summary.saga.编排式.domain.StockUpdatedEvent;
import com.steve.summary.saga.common.model.Inventory;
import com.steve.summary.saga.common.model.Order;
import com.steve.summary.saga.common.repository.InventoryRepository;
import com.steve.summary.saga.common.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Author: STEVE
 * @Description: 库存服务，负责库存的扣减和恢复操作
 * @since: 2025-05-28
 */
@Service
public class InventoryService {

    @Autowired
    private InventoryRepository inventoryRepository;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    /**
     * 处理订单创建事件
     * 1. 检查库存是否充足
     * 2. 扣减库存
     * 3. 发布库存更新事件
     */
    @Transactional
    @EventListener
    public void handleOrderCreated(OrderCreatedEvent event) {
        try {
            Inventory inventory = inventoryRepository.findByProductId(event.getProductId())
                    .orElseThrow(() -> new RuntimeException("Product not found"));
            // 检查库存是否充足
            if (inventory.getStock() < event.getAmount()) {
                throw new RuntimeException("Insufficient stock");
            }
            // 扣减库存
            inventory.setStock(inventory.getStock() - event.getAmount());
            inventoryRepository.save(inventory);
            // 发布库存更新成功事件
            eventPublisher.publishEvent(new StockUpdatedEvent(
                    event.getOrderId(),
                    event.getProductId(),
                    event.getAmount(),
                    true
            ));
        } catch (Exception e) {
            // 发布库存更新失败事件
            eventPublisher.publishEvent(new StockUpdatedEvent(
                    event.getOrderId(),
                    event.getProductId(),
                    event.getAmount(),
                    false
            ));
            throw e;
        }
    }

    /**
     * 处理订单取消事件，恢复已扣减的库存
     */
    @Transactional
    @EventListener
    public void handleOrderCancelled(OrderCancelledEvent event) {
        Order order = orderRepository.findById(event.getOrderId())
                .orElseThrow(() -> new RuntimeException("Order not found"));
        Inventory inventory = inventoryRepository.findByProductId(order.getProductId())
                .orElseThrow(() -> new RuntimeException("Product not found"));
        // 恢复库存
        inventory.setStock(inventory.getStock() + order.getAmount());
        inventoryRepository.save(inventory);
    }

}
